package com.goufn.permission.controller;

import com.goufn.permission.common.result.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.metrics.MetricsEndpoint;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.net.InetAddress;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

@RestController
@RequestMapping("/monitor")
public class MonitorController {

    @Autowired
    private MetricsEndpoint metricsEndpoint;

    private static final long START_TIME = System.currentTimeMillis();
    
    private static long totalRequests = 0;
    private static long currentRequests = 0;
    private static Map<String, Date> onlineUsers = new HashMap<>();

    @GetMapping("/service")
    public CommonResult getServiceInfo(HttpServletRequest request) {
        Map<String, Object> serviceInfo = new HashMap<>();
        
        try {
            RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
            Properties props = System.getProperties();
            
            // 服务器信息
            serviceInfo.put("serverIp", InetAddress.getLocalHost().getHostAddress());
            serviceInfo.put("serverHostname", InetAddress.getLocalHost().getHostName());
            serviceInfo.put("osName", props.getProperty("os.name"));
            serviceInfo.put("osArch", props.getProperty("os.arch"));
            serviceInfo.put("osVersion", props.getProperty("os.version"));
            
            // 服务运行信息
            serviceInfo.put("startTime", new Date(START_TIME));
            serviceInfo.put("runningTime", (System.currentTimeMillis() - START_TIME) / 1000 + "秒");
            serviceInfo.put("javaVersion", props.getProperty("java.version"));
            serviceInfo.put("javaHome", props.getProperty("java.home"));
            
            // 请求统计
            totalRequests++;
            currentRequests++;
            serviceInfo.put("totalRequests", totalRequests);
            serviceInfo.put("currentRequests", currentRequests);
            serviceInfo.put("activeThreads", Thread.activeCount());
            
            // 系统负载
            com.sun.management.OperatingSystemMXBean operatingSystemMXBean = 
                (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
            serviceInfo.put("systemCpuLoad", String.format("%.2f%%", operatingSystemMXBean.getSystemCpuLoad() * 100));
            serviceInfo.put("processCpuLoad", String.format("%.2f%%", operatingSystemMXBean.getProcessCpuLoad() * 100));
            serviceInfo.put("totalMemory", operatingSystemMXBean.getTotalPhysicalMemorySize() / 1024 / 1024 + "MB");
            serviceInfo.put("freeMemory", operatingSystemMXBean.getFreePhysicalMemorySize() / 1024 / 1024 + "MB");
            
            // 在线用户统计（示例，实际应该从session或token管理器中获取）
            serviceInfo.put("onlineUsers", onlineUsers.size());
            
        } catch (Exception e) {
            return CommonResult.error("获取服务监控信息失败：" + e.getMessage());
        } finally {
            currentRequests--;
        }
        
        return CommonResult.success(serviceInfo);
    }

    @GetMapping("/system")
    public CommonResult getSystemInfo() {
        Map<String, Object> systemInfo = new HashMap<>();
        
        // JVM信息
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        systemInfo.put("heapMemoryUsage", memoryMXBean.getHeapMemoryUsage());
        systemInfo.put("nonHeapMemoryUsage", memoryMXBean.getNonHeapMemoryUsage());
        
        // 线程信息
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        systemInfo.put("threadCount", threadMXBean.getThreadCount());
        systemInfo.put("peakThreadCount", threadMXBean.getPeakThreadCount());
        
        // 系统属性
        systemInfo.put("javaVersion", System.getProperty("java.version"));
        systemInfo.put("javaHome", System.getProperty("java.home"));
        systemInfo.put("osName", System.getProperty("os.name"));
        systemInfo.put("osArch", System.getProperty("os.arch"));
        
        // CPU使用率
        systemInfo.put("availableProcessors", Runtime.getRuntime().availableProcessors());
        systemInfo.put("systemLoad", ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage());

        return CommonResult.success(systemInfo);
    }

    @GetMapping("/metrics")
    public CommonResult getMetrics() {
        return CommonResult.success(metricsEndpoint.listNames());
    }

    @GetMapping("/health")
    public CommonResult getHealth() {
        Map<String, Object> healthInfo = new HashMap<>();
        
        // 数据库健康状态
        healthInfo.put("database", checkDatabaseHealth());
        
        // JVM状态
        healthInfo.put("jvm", checkJvmHealth());
        
        // 磁盘空间
        healthInfo.put("diskSpace", checkDiskSpace());

        return CommonResult.success(healthInfo);
    }

    private Health checkDatabaseHealth() {
        try {
            // 这里可以添加数据库连接测试
            return Health.up().withDetail("database", "Database is running").build();
        } catch (Exception e) {
            return Health.down().withException(e).build();
        }
    }

    private Health checkJvmHealth() {
        Runtime runtime = Runtime.getRuntime();
        long freeMemory = runtime.freeMemory();
        long totalMemory = runtime.totalMemory();
        long maxMemory = runtime.maxMemory();

        return Health.up()
                .withDetail("free", freeMemory)
                .withDetail("total", totalMemory)
                .withDetail("max", maxMemory)
                .build();
    }

    private Health checkDiskSpace() {
        try {
            java.io.File root = new java.io.File("/");
            long freeSpace = root.getFreeSpace();
            long totalSpace = root.getTotalSpace();

            return Health.up()
                    .withDetail("free", freeSpace)
                    .withDetail("total", totalSpace)
                    .build();
        } catch (Exception e) {
            return Health.down().withException(e).build();
        }
    }
} 